//
//  InspectorQA.m
//  SimpleBrowser
//
//  Created by Ofri Wolfus on 28/03/07.
//  Copyright 2007 Ofri Wolfus. All rights reserved.
//

#import "InspectorQA.h"


@implementation InspectorQA

/*
 * This class's purpose is to make sure the inspector functions properly.
 * Therefor we can take advantage of UITestingKit and let it manage the
 * inspector element for us.
 * All we need to do is provide it with the inspector's name.
 * Since the inspector already exists, we'll get instantiated before testing
 * begins, but if the inspector was in its own non-visible panel, we'd get
 * instantiated only when its visible (or created, in the accessibility terminology).
 */
+ (NSString *)testedElement {
	return @"SimpleBrowser.inspector";
}

- (id)initWithElement:(DPUIElement *)element {
	if ((self = [super initWithElement:element])) {
		browser = [[DPTestSubject anyChildNamed:@"SimpleBrowser.fsBrowser"] retain];
		
		// We watch for value change notification of our inspector.
		// Value change is posted whenever the inspector's text changes.
		[[DPAccessibilityNotificationCenter defaultCenter] addObserver:self
															  selector:@selector(inspectorValueChanged:)
																  name:NSAccessibilityValueChangedNotification
																object:[self UIElement]];
	}
	
	return self;
}

- (void)dealloc {
	// No need to removeObserver from DPAccessibilityNotificationCenter
	// as UITestingKit takes care for that for us.
	[browser release]; browser = nil;
	[super dealloc];
}

// This method finds the last list with selected rows.
// In real life it won't always be the real selected list, but in our example it is.
- (DPUIElement *)findSelectedList {
	NSArray *columns = [browser valueForAttribute:NSAccessibilityColumnsAttribute];
	NSEnumerator *cEnum = [columns reverseObjectEnumerator];
	DPUIElement *scrollView;
	
	while ((scrollView = [cEnum nextObject])) {
		// Find the list element in this scroll view
		// TODO: Incorporate HOM to UITestingKit to make these things easier
		NSEnumerator *childs = [[scrollView children] objectEnumerator];
		DPUIElement *list;
		
		while ((list = [childs nextObject]))
			if ([[list role] isEqualToString:NSAccessibilityListRole])
				break;
		
		if (list && [list valueCountForAttribute:NSAccessibilitySelectedChildrenAttribute] > 0)
			return list;
	}
	
	return nil;
}

// The value of our inspector changed.
// If it's not what we expect it to be we just throw an exception (DPAssert in this case).
- (void)inspectorValueChanged:(NSNotification *)notif {
	DPUIElement *list = [self findSelectedList];
	
	if (list) {
		NSArray *rows = [list selectedChildren];
		NSString *inspectorVal = [[self UIElement] valueForAttribute:NSAccessibilityValueAttribute];
		
		// No selection
		if ([rows count] == 0U) {
			DPAssert([inspectorVal isEqualToString:@"No Selection"],
					 @"Wrong inspector value: %@, expected 'No Selection'.", inspectorVal);
			
		// Single selection
		} else if ([rows count] == 1U) {
			NSString *title = [[rows objectAtIndex:0U] valueForAttribute:NSAccessibilityValueAttribute];
			NSString *inspectorPrefix = [NSString stringWithFormat:@"Name: %@", title];
			
			// inspectorPrefix is created as a specific variable due to macro problems with commas - 
			// can't write DPAssert([[inspectorVal string] hasPrefix: [NSString stringWithFormat:@"..." , ...], ...)
			DPAssert([inspectorVal hasPrefix:inspectorPrefix],  @"Wrong inspector value for single selection.");
			
			// Multiple selections
		} else {
			DPAssert([inspectorVal isEqualToString:@"Multiple Selection"],
					 @"Wrong inspector value: %@, expected 'Multiple Selection'.", inspectorVal);
		}
	}
}

@end
